package refactoredBankSystem;

/**
 * The CheckingAccount class.
 * @author (refactorers) Sagar Kamboj, Yong Yu Wang
 *
 */
public class CheckingAccount 
{
	/**
	 * The checking account number.
	 */
	private int fAccountNumber;
	
	/**
	 * If using debit is allowed or not.
	 */
	private boolean fDebitAllowed;
	
	/**
	 * The debit amount in the checking account.
	 */
	private double fDebitAmount;
	
	/**
	 * The balance of the account.
	 */
	private double fBalance;
	
	/**
	 * Cost associated with the account.
	 */
	private static double costs = 1; // per period there is a cost associated with this account
									// that equals 1 pound
	
	/**
	 * The debit rate of the account.
	 */
	private static final double DEBIT_RATE = 4.7;
	
	/**
	 * The credit card associated with the account.
	 */
	private static CreditCard fCreditCard;
	
	/**
	 * The savings account associated with the checking account.
	 */
	private static SavingsAccount fSavingsAccount;
	
	/**
	 * The debit card associated with the account.
	 */
	private static DebitCard fDebitCard;
	
	/**
	 *  The next account number of the user.
	 */
	private static int fNextAccountNumber = 0;
	
	/**
	 * The current customer.
	 */
	private Customer currentCustomer;
	
	
	/**
	 * Creates a CheckingAccount with the customer parameter.
	 * 
	 * @param newCustomer making a checking account.
	 */
	public CheckingAccount(final Customer newCustomer)
	{
		// Calling the second constructor.
		this(newCustomer, 0);
		fDebitAllowed = false;
	}
	
	/**
	 * Creates a CheckingAccount with the customer parameter and a debit amount.
	 * 
	 * @param newCustomer making a checking account.
	 * @param debit amount.
	 */
	public CheckingAccount(final Customer newCustomer, final float debit)
	{
		currentCustomer = newCustomer;
		fAccountNumber = fNextAccountNumber;
		fNextAccountNumber++;
		fDebitAllowed = true;
		fDebitAmount = debit;
	}
	
	/**
	 * Create a checkingAccount using the account number.
	 * 
	 * @param accountnumber of the user 
	 */
	public CheckingAccount(final int accountnumber)
	{
		fAccountNumber = accountnumber;
	}
	
	/**
	 * Determine the costs of the account.
	 */
	public void determineCosts()
	{
		fBalance = fBalance - costs;
		if(fBalance < 0)
		{
			fBalance = fBalance - (fBalance * DEBIT_RATE / 100);
		}
	}
	
	/**
	 * Print out the information of the bank account.
	 */
	public void print()
	{
		if (currentCustomer.getName() == null) {
			currentCustomer.setName("NO NAME INFO");
		}
		if (currentCustomer.getStreet() == null) {
			currentCustomer.setStreet("NO STREET INFO");
		}
		if (currentCustomer.getZipCode() == null) {
			currentCustomer.setZipCode("NO ZIPCODE INFO");
		}
		if (currentCustomer.getTown() == null) {
			currentCustomer.setTown("NO TOWN INFO");
		}
		if (currentCustomer.getCountry() == null) {
			currentCustomer.setCountry("NO COUNTRY INFO");
		}
		System.out.println("**************************************");
		System.out.println("Savings account:     " + fAccountNumber);
		System.out.println("Account holder name: " + currentCustomer.getName());
		System.out.println("Address:             " + currentCustomer.getStreet());
		System.out.print("                     " + currentCustomer.getZipCode());
		System.out.println(" " + currentCustomer.getTown());
		System.out.println(currentCustomer.getCountry().toUpperCase());
		System.out.println("**************************************");
		System.out.println("Balance:  " + fBalance);
		System.out.println("**************************************");
	}
	
	/**
	 * Withdraw an amount from the bank.
	 * @param amount to be withdrawn.
	 * @return amount withdrawn.
	 */
	public boolean withdrawal(final double amount)
	{
		if(((fBalance - amount) < 0) && (!fDebitAllowed))
		{
			return false;
		}
		else if((fBalance - amount) < -fDebitAmount)
		{
			fBalance = fBalance - amount;
			return true;
		}
		else
		{
			return false;
		}
	}
	
	/**
	 * Adds that amount to the balance.
	 * @param amount to add.
	 */
	public void verseMoney(final double amount)
	{
		fBalance += amount;
	}
	
	/**
	 * Creates a CheckingAccount with the specified parameters.
	 * 
	 * @param currentCustomer applying for the card.
	 * @param accountNumber that is going to be associated with the credit card.
	 */
	public boolean applyForCreditCard(final Customer currentCustomer, final int accountNumber)
	{
		if(fBalance < 0)
		{
			return false;
		}
		if(fBalance <= 2500)
		{
			fCreditCard = new CreditCard(currentCustomer);
		}
		else
		{
			fCreditCard = new CreditCard(currentCustomer, 5000);
		}
		return true;
	}
	
	/**
	 * Get back the balance.
	 * @return the balance.
	 */
	public double getBalance()
	{
		return fBalance;
	}
	
	/**
	 * Add the amount to the balance.
	 * @param amount to be added.
	 */
	public void increaseBalance(final double amount)
	{
		fBalance += amount;
	}
	
	/**
	 * Take out the amount from the balance.
	 * 
	 * @param amount to be taken out.
	 */
	public void decreaseBalance(final double amount)
	{
		fBalance -= amount;
	}

	/**
	 * Returns back the debit amount.
	 * 
	 * @return the debit amount.
	 */
	public double getDebitAmount()
	{
		return fDebitAmount;
	}

	/**
	 * Sets the balance to the amount specified.
	 * @param amount the balance is set.
	 */
	public void setBalance(final double amount)
	{
		fBalance = amount;	
	}

	/**
	 * Get the account number.
	 * @return the account number.
	 */
	public int getAccountNumber() 
	{
		return fAccountNumber;	
	}
	
	/**
	 * Get the current customer belonging to this class.
	 * @return	The current customer in this class.
	 */
	public Customer getCustomer() {
		return currentCustomer;
	}
	
	/**
	 * Sets the customer in this class to a new one.
	 * @param newCustomer	the new customer to set.
	 */
	public void setCustomer(final Customer newCustomer) {
		currentCustomer = newCustomer;
	}
	
	/**
	 * Gets the SavingsAccount object associated with this class.
	 * @return the SavingsAccount object
	 */
	public SavingsAccount getSavingsAccount() {
		return fSavingsAccount;
	}
	
	/**
	 * Gets the DebitCard object associated with this class.
	 * @return the DebitCard object
	 */
	public DebitCard getDebitCard() {
		return fDebitCard;
	}
	
	/**
	 * Sets current SavingsAccount to a new account.
	 * @param newAccount the new SavingsAccount to set.
	 */
	public void setSavingsAccount(final SavingsAccount newAccount) {
		fSavingsAccount = newAccount;
	}
	
	/**
	 * Sets current DebitCard to a new card.
	 * @param newCard the new card to set.
	 */
	public void setDebitCard(final DebitCard newCard) {
		fDebitCard = newCard;
	}
	
	/**
	 * Sets the fCreditCard in this class to a new one.
	 * @param fCreditCard	the new credit card to set.
	 */
	public void setFCreditCard(final CreditCard newCard) {
		fCreditCard = newCard;
	}
	
	/**
	 * Gets the fCreditCard object associated with this class.
	 * @return the CreditCard object
	 */
	public CreditCard getFCreditCard() {
		return fCreditCard;
	}
	
	/**
	 * Sets the fDebitAllowed value in this class.
	 * @param fDebitAllowed	the value to set.
	 */
	public void setFDebitAllowed(final boolean value) {
		fDebitAllowed = value;
	}
	
	/**
	 * Gets the fDebitAllowed value in this class.
	 * @return the fDebitAllowed value
	 */
	public boolean getFDebitAllowed() {
		return fDebitAllowed;
	}
	
	/**
	 * Get the fNextAccountNumber
	 * @return the account number.
	 */
	public int getFNextAccountNumber() 
	{
		return fNextAccountNumber;	
	}
	
	/**
	 * Sets the fNextAccountNumber for this account to a new value.
	 * @param newNumber the new number to set.
	 */
	public void setFNextAccountNumber(final int newNumber) 
	{
		fNextAccountNumber = newNumber;	
	}
	
	public boolean equals(final Object o)
	{
		if(fAccountNumber == ((CheckingAccount)o).fAccountNumber)
			return true;
		else
			return false;
				
	}
}
